package gframework.bean.textField;

import gframework.bean.Util;
import gframework.bean.field.GPlainDocument;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.text.DecimalFormat;
import java.util.HashSet;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.MaskFormatter;

public class GTextField extends javax.swing.JFormattedTextField {

    public final static String MASK_DATA = "Data";
    public final static String MASK_MESANO = "Mês/Ano";
    public final static String MASK_NUMERO = "Numero";
    public final static String MASK_DECIMAL0 = "Decimal 0";
    public final static String MASK_DECIMAL1 = "Decimal 1";
    public final static String MASK_DECIMAL2 = "Decimal 2";
    public final static String MASK_DECIMAL3 = "Decimal 3";
    public final static String MASK_CPF = "CPF";
    public final static String MASK_CNPJ = "CNPJ";
    public final static String MASK_CEP = "Cep";
    public final static String MASK_MERCADOLOGICO3 = "Mercadológico 3";
    public final static String MASK_MERCADOLOGICO4 = "Mercadológico 4";
    public final static String MASK_MERCADOLOGICO5 = "Mercadológico 5";
    public final static String MASK_NCM = "Ncm";
    public final static String MASK_AUTOMACAO = "Automação";
    public final static String MASK_BIBLIOTECA_PDV = "Biblioteca PDV";
    public final static String MASK_HORA = "Hora";
    public final static String MASK_CUSTO = "Custo";
    public final static String MASK_DUN14 = "Dun 14";
    public final static String MASK_TELEFONE = "Telefone";
    public final static String MASK_DESCONTO = "Desconto";
    private MaskFormatter formato = new MaskFormatter();
    private String mascara = "";
    private int columns = 0;
    private boolean caixaAlta = true;
    private boolean selecionaTexto = true;
    private boolean negativo = false;
    private boolean teclaEnter = true;

    public GTextField() {
        initComponents();

        setTeclaEnter(true);

        setDocument(new GPlainDocument());
    }

    @Override
    public int getColumns() {
        return columns;
    }

    public void setInt(int i_int) {
        this.setText(String.valueOf(i_int));
    }

    public void setLong(long i_long) {
        this.setText(String.valueOf(i_long));
    }

    @Override
    public void setColumns(int i_columns) {
        this.columns = i_columns;

        ((GPlainDocument) getDocument()).setColumns(i_columns);
    }

    public void setCaixaAlta(boolean i_caixaAlta) {
        caixaAlta = i_caixaAlta;
        ((GPlainDocument) getDocument()).setCaixaAlta(i_caixaAlta);
    }

    public boolean isCaixaAlta() {
        return caixaAlta;
    }
    
    public String getClipText() {
        if (getMascara().equals(MASK_DATA)) {
            return getText().replace(" ", "").replace("/", "");

        } else if (getMascara().equals(MASK_MESANO)) {
            return getText().replace(" ", "").replace("/", "");

        } else if (getMascara().equals(MASK_CPF)) {
            return getText().replace(" ", "").replace(".", "").replace("-", "");

        } else if (getMascara().equals(MASK_CNPJ)) {
            return getText().replace(" ", "").replace(".", "").replace("/", "").replace("-", "");

        } else if (getMascara().equals(MASK_CEP)) {
            return getText().replace(" ", "").replace("-", "");

        } else if ((getMascara().equals(MASK_MERCADOLOGICO3)) || (getMascara().equals(MASK_MERCADOLOGICO4)) || (getMascara().equals(MASK_MERCADOLOGICO5)) || (getMascara().equals(MASK_NCM))) {
            return getText().replace(" ", "").replace(".", "");

        } else if (getMascara().equals(MASK_BIBLIOTECA_PDV)) {
            return getText().replace(" ", "").replace(".", "");

        } else if (getMascara().equals(MASK_HORA)) {
            return getText().replace(" ", "").replace(":", "");

        } else if (getMascara().equals(MASK_TELEFONE)) {
            return getText().replace(" ", "").replace("(", "").replace(")", "").replace("-", "");

        } else if (getMascara().equals(MASK_DESCONTO)) {
            return getText().replace(" ", "").replace(",", "").replace(".", "");

        } else {
            return getText();
        }
    }

    public String getMascara() {
        return mascara;
    }

    public void setMascara(String i_mascara) {
        try {
            String mascaraAnterior = this.mascara;
            this.mascara = i_mascara;

            formato.install(null);

            if (i_mascara.equals(MASK_NUMERO)) {
                setHorizontalAlignment(JTextField.LEADING);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.NUMERIC);

                if (mascaraAnterior.equals(MASK_DECIMAL3) && !getText().equals("")) {
                    setDouble(getDouble());
                }

            } else if (i_mascara.equals(MASK_DATA)) {
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.ALPHA_NUMERIC);
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("##/##/####");
                formato.install(this);

            } else if (i_mascara.equals(MASK_TELEFONE)) {
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.ALPHA_NUMERIC);
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("(##) #########");
                formato.install(this);

            } else if (i_mascara.equals(MASK_MESANO)) {
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.ALPHA_NUMERIC);
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("##/####");
                formato.install(this);

            } else if (i_mascara.equals(MASK_DECIMAL0)) {
                setHorizontalAlignment(JTextField.RIGHT);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.FLOAT);
                ((GPlainDocument) getDocument()).setCasaDecimal(0);

            } else if (i_mascara.equals(MASK_DECIMAL1)) {
                setHorizontalAlignment(JTextField.RIGHT);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.FLOAT);
                ((GPlainDocument) getDocument()).setCasaDecimal(1);

            } else if (i_mascara.equals(MASK_DECIMAL2)) {
                setHorizontalAlignment(JTextField.RIGHT);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.FLOAT);
                ((GPlainDocument) getDocument()).setCasaDecimal(2);

            } else if (i_mascara.equals(MASK_DECIMAL3)) {
                setHorizontalAlignment(JTextField.RIGHT);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.FLOAT);
                ((GPlainDocument) getDocument()).setCasaDecimal(3);

                if (mascaraAnterior.equals(MASK_NUMERO) && !getText().equals("")) {
                    setDouble(getDouble());
                }

            } else if (i_mascara.equals(MASK_CNPJ)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("##.###.###/####-##");
                formato.install(this);

            } else if (i_mascara.equals(MASK_CPF)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("###.###.###-##");
                formato.install(this);

            } else if (i_mascara.equals(MASK_CEP)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("#####-###");
                formato.install(this);

            } else if (i_mascara.equals(MASK_NCM)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("####.##.##");
                formato.install(this);

            } else if (i_mascara.equals(MASK_MERCADOLOGICO3)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("###.###.###");
                formato.install(this);

            } else if (i_mascara.equals(MASK_MERCADOLOGICO4)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("###.###.###.###");
                formato.install(this);

            } else if (i_mascara.equals(MASK_MERCADOLOGICO5)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("###.###.###.###.###");
                formato.install(this);

            } else if (i_mascara.equals(MASK_AUTOMACAO)) {
                setColumns(13);
                setHorizontalAlignment(JTextField.LEADING);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.NUMERIC);

            } else if (i_mascara.equals(MASK_DUN14)) {
                setColumns(14);
                setHorizontalAlignment(JTextField.LEADING);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.NUMERIC);

            } else if (i_mascara.equals(MASK_BIBLIOTECA_PDV)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("##.##.##");
                formato.install(this);

            } else if (i_mascara.equals(MASK_HORA)) {
                setHorizontalAlignment(JTextField.LEADING);
                formato.setMask("##:##");
                formato.install(this);

            } else if (i_mascara.equals(MASK_CUSTO)) {
                setHorizontalAlignment(JTextField.RIGHT);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.FLOAT);
                ((GPlainDocument) getDocument()).setCasaDecimal(3);

            } else if (i_mascara.equals(MASK_DESCONTO)) {
                setHorizontalAlignment(JTextField.RIGHT);
                ((GPlainDocument) getDocument()).setAcceptedChars(GPlainDocument.NUMERIC + "+");
                ((GPlainDocument) getDocument()).setCasaDecimal(0);
            }

        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "GTextField", JOptionPane.WARNING_MESSAGE);
        }
    }

    @Override
    public void setText(String t) {
        super.setText(t);

        if (this.isEnabled() && this.isEditable() && this.isFocusable()) {
            setBackground(UIManager.getColor("TextField.background"));
        }
    }

    public void clear() throws Exception {
        this.setText("");
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                formActionPerformed(evt);
            }
        });
        addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                formFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                formFocusLost(evt);
            }
        });
        addInputMethodListener(new java.awt.event.InputMethodListener() {
            public void caretPositionChanged(java.awt.event.InputMethodEvent evt) {
            }
            public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) {
                formInputMethodTextChanged(evt);
            }
        });
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                formKeyTyped(evt);
            }
        });
    }// </editor-fold>//GEN-END:initComponents

    private void formFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_formFocusLost
        try {
            if (mascara.equals(MASK_DECIMAL0)) {
                if (!getText().equals("")) {
                    double valor = Double.parseDouble(getText());
                    setDouble(valor);
                }
            } else if (mascara.equals(MASK_DECIMAL1)) {
                if (!getText().equals("")) {
                    double valor = 0;

                    if ((getText().indexOf(".") == -1) && (getText().indexOf(",") == -1)) {
                        valor = Double.parseDouble(getText()) / 10;
                    } else {
                        valor = Double.parseDouble(getText().replace(",", "."));
                    }

                    ((GPlainDocument) getDocument()).setColumns(0);
                    setDouble(valor);
                }
            } else if (mascara.equals(MASK_DECIMAL2)) {
                if (!getText().equals("")) {
                    double valor = 0;

                    if ((getText().indexOf(".") == -1) && (getText().indexOf(",") == -1)) {
                        valor = Double.parseDouble(getText()) / 100;
                    } else {
                        valor = Double.parseDouble(getText().replace(",", "."));
                    }

                    ((GPlainDocument) getDocument()).setColumns(0);
                    setDouble(valor);
                }
            } else if (mascara.equals(MASK_DECIMAL3)) {
                if (!getText().equals("")) {
                    double valor = 0;

                    if ((getText().indexOf(".") == -1) && (getText().indexOf(",") == -1)) {
                        valor = Double.parseDouble(getText()) / 1000;
                    } else {
                        valor = Double.parseDouble(getText().replace(",", "."));
                    }

                    ((GPlainDocument) getDocument()).setColumns(0);
                    setDouble(valor);
                }
            } else if (mascara.equals(MASK_DATA)) {
                if (!getClipText().equals("")) {
                    if (!Util.isDataValida(getText())) {
                        throw new Exception("Data inválida!");
                    }
                }
            } else if (mascara.equals(MASK_MESANO)) {
                if (!getClipText().equals("")) {
                    if (!Util.isMesAnoValido(getText())) {
                        throw new Exception("Data inválida!");
                    }
                }
            } else if (mascara.equals(MASK_HORA)) {
                if (!getClipText().equals("")) {
                    if (!Util.isHoraValida(getText())) {
                        throw new Exception("Hora inválida!");
                    }
                }
            } else if (mascara.equals(MASK_CNPJ)) {
//                if (!this.getClipText().equals("")) {
//                    if (!Util.isCNPJValido(this.getClipText())) {
//                        throw new Exception("CNPJ inválido!");
//                    }
//                }
            } else if (mascara.equals(MASK_CPF)) {
//                if (!this.getClipText().equals("")) {
//                    if (!Util.isCPFValido(this.getClipText())) {
//                        throw new Exception("CPF inválido!");
//                    }
//                }
            } else if (mascara.equals(MASK_NCM)) {
                if (!this.getClipText().equals("")) {
                    if (this.getClipText().length() != 8) {
                        throw new Exception("Ncm inválido!");
                    }
                }
            } else if (mascara.equals(MASK_MERCADOLOGICO3)) {
                if (!this.getClipText().equals("")) {
                    if (this.getClipText().length() != 9) {
                        throw new Exception("Mercadológico inválido!");
                    }
                }
            } else if (mascara.equals(MASK_MERCADOLOGICO4)) {
                if (!this.getClipText().equals("")) {
                    if (this.getClipText().length() != 12) {
                        throw new Exception("Mercadológico inválido!");
                    }
                }
            } else if (mascara.equals(MASK_MERCADOLOGICO5)) {
                if (!this.getClipText().equals("")) {
                    if (this.getClipText().length() != 15) {
                        throw new Exception("Mercadológico inválido!");
                    }
                }
            } else if (mascara.equals(MASK_BIBLIOTECA_PDV)) {
                if (!this.getClipText().equals("")) {
                    if (this.getClipText().length() != 6) {
                        throw new Exception("Versão de Biblioteca inválido!");
                    }
                }
            } else if (mascara.equals(MASK_AUTOMACAO)) {
                if (!getText().equals("")) {
                    this.setText(Util.formatNumber(getLong(), 13));

                    if (!Util.isAutomacaoValido(getLong()) || this.getLong() == 0) {
                        throw new Exception("Código de barras inválido!");
                    }
                }
            } else if (mascara.equals(MASK_DUN14)) {
                if (!getText().equals("")) {
                    this.setText(Util.formatNumber(getLong(), 14));

                    if (!Util.isDun14Valido(getLong()) || this.getLong() == 0) {
                        throw new Exception("Código Dun 14 inválido!");
                    }
                }
            } else if (mascara.equals(MASK_CUSTO)) {
                if (!getText().equals("")) {
                    double valor = 0;

                    if ((getText().indexOf(".") == -1) && (getText().indexOf(",") == -1)) {
                        valor = Double.parseDouble(getText()) / 100;
                    } else {
                        valor = Double.parseDouble(getText().replace(",", "."));
                    }

                    ((GPlainDocument) getDocument()).setColumns(0);

                    setDouble(valor);
                }
            }

        } catch (Exception ex) {
            Util.exibirMensagemErro(ex.getMessage(), "GTextField");

            Runnable doFocus = new Runnable() {

                public void run() {
                    requestFocus();
                }
            };

            SwingUtilities.invokeLater(doFocus);
        }
    }//GEN-LAST:event_formFocusLost

    private void formFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_formFocusGained
        if (mascara.equals(MASK_DECIMAL0)) {
            if (!getText().equals("")) {
                setText(getText().replace(".", ""));
                ((GPlainDocument) getDocument()).setColumns(getColumns());
            }
        } else if (mascara.equals(MASK_DECIMAL1)) {
            if (!getText().equals("")) {
                setText(getText().replace(".", ""));
                ((GPlainDocument) getDocument()).setColumns(getColumns());
            }
        } else if (mascara.equals(MASK_DECIMAL2)) {
            if (!getText().equals("")) {
                setText(getText().replace(".", ""));
                ((GPlainDocument) getDocument()).setColumns(getColumns());
            }
        } else if (mascara.equals(MASK_DECIMAL3)) {
            if (!getText().equals("")) {
                setText(getText().replace(".", ""));
                ((GPlainDocument) getDocument()).setColumns(getColumns());
            }
        } else if (mascara.equals(MASK_CUSTO)) {
            if (!getText().equals("")) {
                setText(getText().replace(".", ""));
                ((GPlainDocument) getDocument()).setColumns(getColumns());
            }
        } else if (mascara.equals(MASK_DESCONTO)) {
            if (!getText().equals("")) {
                setText(getText().replace(".", ""));
                ((GPlainDocument) getDocument()).setColumns(getColumns());
            }
        }

        if (isEditable() && isSelecionaTexto()) {
            Runnable doSelect = new Runnable() {

                public void run() {
                    selectAll();
                }
            };

            SwingUtilities.invokeLater(doSelect);
        }
    }//GEN-LAST:event_formFocusGained

    private void formKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyTyped
        if (this.isEnabled() && this.isEditable() && this.isFocusable()) {
            setBackground(UIManager.getColor("TextField.background"));
        }
    }//GEN-LAST:event_formKeyTyped

    private void formKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyPressed
        try {
            if(evt.isAltDown()){
                if (evt.getKeyCode() == KeyEvent.VK_D) {
                    if (this.mascara.equals(MASK_DATA)) {
                        this.setText(Util.getDataAtual());
                        this.transferFocus();

                    } else if (this.mascara.equals(MASK_MESANO)) {
                        this.setText(Util.getDataAtual().substring(3, 10));
                        this.transferFocus();

                    } else if (this.mascara.equals(MASK_HORA)) {
                        this.setText(Util.getHoraAtual());
                        this.transferFocus();
                    }
                }
            }

        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "GTextField", JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_formKeyPressed

    private void formActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_formActionPerformed
    }//GEN-LAST:event_formActionPerformed

    private void formInputMethodTextChanged(java.awt.event.InputMethodEvent evt) {//GEN-FIRST:event_formInputMethodTextChanged
    }//GEN-LAST:event_formInputMethodTextChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
    public void setDouble(double d) {
        if (getMascara().equals(MASK_DECIMAL0)) {
            setText(new DecimalFormat("###,##0").format(d));

        } else if (getMascara().equals(MASK_DECIMAL1)) {
            setText(new DecimalFormat("###,##0.0").format(d));

        } else if (getMascara().equals(MASK_DECIMAL2)) {
            setText(new DecimalFormat("###,##0.00").format(d));

        } else if (getMascara().equals(MASK_DECIMAL3)) {
            setText(new DecimalFormat("###,##0.000").format(d));

        } else if (getMascara().equals(MASK_NUMERO)) {
            setText(new DecimalFormat("###,##0").format(d));

        } else if (getMascara().equals(MASK_CUSTO)) {
            String valor = new DecimalFormat("###,##0.000").format(d);

            if ((valor.substring(valor.length() - 1, valor.length()).equals("0"))) {
                setText(new DecimalFormat("###,##0.00").format(d));
            } else {
                setText(new DecimalFormat("###,##0.000").format(d));
            }
        } else {
            setText(String.valueOf(d));
        }
    }

    public int getInt() throws Exception {
        if (this.getClipText().equals("")) {
            return 0;
        } else {
            return Integer.parseInt(this.getClipText());
        }
    }

    public long getLong() throws Exception {
        if (this.getClipText().equals("")) {
            return 0;
        } else {
            return Long.parseLong(this.getClipText());
        }
    }

    public double getDouble() throws Exception {
        if (this.getClipText().equals("")) {
            return 0;
        } else {
            return Double.parseDouble(getText().replace(".", "").replace(",", "."));
        }
    }

    public boolean isSelecionaTexto() {
        return selecionaTexto;
    }

    public void setSelecionaTexto(boolean selecionaTexto) {
        this.selecionaTexto = selecionaTexto;
    }

    public boolean isNegativo() {
        return negativo;
    }

    public void setNegativo(boolean negativo) {
        this.negativo = negativo;
        ((GPlainDocument) getDocument()).setNegativo(negativo);
    }

    public boolean isTeclaEnter() {
        return teclaEnter;
    }

    public void setTeclaEnter(boolean teclaEnter) {
        this.teclaEnter = teclaEnter;

        HashSet kTab = new HashSet(1);
        kTab.add(KeyStroke.getKeyStroke("TAB"));

        if (teclaEnter) {
            kTab.add(KeyStroke.getKeyStroke("ENTER"));
        }

        setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, kTab);
    }
}